package effectivejava.no79;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Package: effectivejava.no79
 * @ClassName: ObservableSet
 * @Author: lujieni
 * @Description:
 * @Date: 2021-04-08 10:12
 * @Version: 1.0
 */
public class ObservableSet<E> {

    private final List<SetObserver<E>> observers= new CopyOnWriteArrayList<>();


    public void addObserver(SetObserver<E> observer) {
            observers.add(observer);
    }

    public Boolean removeObserver(SetObserver<E> observer) {
         return observers.remove(observer);
    }

    private void notifyElementAdded(E element) {
        for (SetObserver<E> observer : observers) { //得到的是原始数据的快照
            observer.added(this, element);
        }
    }

    public Boolean add(E element) {
        notifyElementAdded(element);
        return true;
    }


    public static void main(String[] args) {
        ObservableSet<Integer> set = new ObservableSet<>();
        //加入观察者
        //ConcurrentModificationException:在遍历List的时候不能删除element
        set.addObserver(new SetObserver<Integer>() {
            public void added(ObservableSet<Integer> s, Integer e) {
                System.out.println(e);
                if (e == 23)
                    s.removeObserver(this);
            }
        });

        // 死锁:exec.submit(() -> s.removeObserver(this)).get();是blocking的
       /* set.addObserver(new SetObserver<Integer>() {
            public void added(ObservableSet<Integer> s, Integer e) {
                System.out.println(e);
                if (e == 23) {
                    ExecutorService exec = Executors.newSingleThreadExecutor();
                    try {
                         exec.submit(() -> s.removeObserver(this)).get();
                    }catch (Exception ex) {
                        throw new AssertionError (ex);
                    } finally {
                        exec.shutdown();
                    }
                }
            }
        });*/


        for (int i = 0; i < 100; i++){
            set.add(i);
        }



    }






}